package com.qf.base.utils;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class SyncBatchCallUtil {
    private static ExecutorService executorPool;
    static {
        //线程池维护线程的最少数量
        //线程池至少会保持改数量的线程存在，即使没有任何任务执行
        int corePoolSize=5;
        //线程池维护线程的最大数量
        int maxPoolSize=10;
        //线程池维护的线程最大的空闲时间
        long keepaLiveTime=10;
        //空闲时间的单位
        TimeUnit unit=TimeUnit.SECONDS;
        //线程池使用的缓冲队列
        // ArrayBlockingQueue  有界队列，需要指定队列的大小，如果队列满了，会触发线程的RejectedExecutionHandler的
        //LinkedBlockingQueue 无界队列，可以无限向队列中添加任务，直到内存溢出
        //SynchronousQueue  阻塞队列  每一个put任务都必须等待一个task，可以理解为容量只有1的队列
        //PriorityBlockingQueue  优先队列，设置任务的时候，可以
        BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(6);
        //线程工厂
        ThreadFactory threadFactory=new UserThreadFactory("batch");
        //队列满了的handler
        RejectedExecutionHandler handler=new MyRejectPolicy();
        /**
         * 实例化线程池
         */
        executorPool=new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepaLiveTime,unit,workQueue,threadFactory,handler);

    }

    /***
     * 外界可以调用这个方法
     * 传入一个runnable对象，使用线程池来执行
     * @Author 67517
     * @Description //TODO
     * @Param [task]
     * @return void
     */
    public static void execute(Runnable task){
        executorPool.execute(task);
    }
    /**
     * 对外界提供任务
     * 处理一组任务
     *
     */
    public static boolean batch(Task ... tasks){
        if (!createTasks(tasks)){
            return false;
        }
        return true;
    }

    /**
     * 创建一组任务,为了让多个线程阻塞住
     */
    private static CountDownLatch countDownLatch;
    private static boolean createTasks(Task[] tasks){
        countDownLatch=new CountDownLatch(tasks.length);
        for (int i = 0; i <tasks.length ; i++) {
            tasks[i].setCountDownLatch(countDownLatch);
        }
        for (int i = 0; i <tasks.length ; i++) {
            executorPool.execute(tasks[i]);
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
//            e.printStackTrace();
            return false;
        }
        return true;
    }


    public static abstract class Task implements Runnable{
        public abstract void exe();
        private CountDownLatch countDownLatch;
        public void setCountDownLatch(CountDownLatch countDownLatch){
            this.countDownLatch=countDownLatch;
        }
        @Override
        public void run() {
            exe();
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 创建线程工厂
     */
    static class UserThreadFactory implements ThreadFactory{
        private final String namePrefix;
        private final AtomicInteger nextId=new AtomicInteger(1);
        UserThreadFactory(String groupName){
            namePrefix="From UserThreadFactory's"+groupName+"-Worker-";

        }
        @Override
        public Thread newThread(Runnable task) {
            String name=namePrefix+nextId.getAndIncrement();
            Thread thread=new Thread(null,task,name);
            return thread;
        }
    }
    /**
     * 我们使用有界队列，当队列满了，会触发RejectedExecutionHandler
     *
     */
    static class MyRejectPolicy implements RejectedExecutionHandler{

        @Override
        public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
            System.out.println(task);
        }
    }

}
